package sg.edu.nus.dbd.action;

import java.sql.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanArrayDataSource;
import net.sf.jasperreports.engine.export.JRHtmlExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
import net.sf.jasperreports.j2ee.servlets.ImageServlet;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import sg.edu.nus.dbd.biz.DashboardBiz;
import sg.edu.nus.dbd.biz.ConfigurationBiz;
import sg.edu.nus.dbd.formbean.ChartData;
import sg.edu.nus.dbd.formbean.ChartDataItem;
import sg.edu.nus.dbd.formbean.DetailParamData;
import sg.edu.nus.dbd.formbean.GaugeChartData;
import sg.edu.nus.dbd.formbean.ThresholdConfig;
import sg.edu.nus.dbd.util.Constants;
import sg.edu.nus.dbd.util.DateUtil;
import sg.edu.nus.dbd.util.MyLogger;

public class DashboardAction extends BaseAction {

	public ActionForward performAction(ActionMapping mapping, ActionForm form,
			HttpServletRequest req, HttpServletResponse res) throws Exception {
		try {
			MyLogger.debug(this.getClass(), "execute::Start...");
			HttpSession session = req.getSession(false);

			// Get the selected param
			String currentParam = req.getParameter("param");

			if (currentParam == null) {
				// Try using the previous selection
				currentParam = (String) session
						.getAttribute("CurrentParameter");
				if (currentParam == null) {
					// Default to first param if no selection has been made
					Set paramKeys = Constants.DASHBOARD_PARAMS.keySet();
					Iterator i = paramKeys.iterator();
					currentParam = (String) i.next();
				}
			}
			MyLogger.debug("Generate report for param:" + currentParam);

			session.setAttribute("CurrentParameter", currentParam);

			// Get the average value in the last 7 days
			Date endDate = new Date(new java.util.Date().getTime());
			Date startDate = DateUtil.addDayToDate(endDate, -7);
			String reportChartContent = getGaugeChartHTMLContent(req,
					currentParam, startDate, endDate);

			GaugeChartData gaugeChartData = new GaugeChartData(currentParam,
					reportChartContent);

			req.setAttribute("gaugeChart", gaugeChartData);

			DetailParamData level1Data = new DashboardBiz()
					.getLevel1Statistics(currentParam, startDate, endDate);

			ThresholdConfig thConfig = new ConfigurationBiz()
					.getThresholdParameter(currentParam);

			if (!(Boolean) Constants.DASHBOARD_PARAMS_INVERSE.get(currentParam)) {
				if (level1Data.getAggregatedValue() >= thConfig
						.getCriticalLevel()) {
					req.setAttribute("showTuningGuide", true);

				}
			} else {
				if (level1Data.getAggregatedValue() <= thConfig
						.getWarningLevel()) {
					req.setAttribute("showTuningGuide", true);
				}
			}

			return mapping.findForward("success");

		} catch (Exception e) {
			MyLogger.error(this.getClass(), e);
			return mapping.findForward("error");
		}
	}

	private String getGaugeChartHTMLContent(HttpServletRequest request,
			String parameterName, Date startDate, Date endDate) {
		StringBuffer sb = new StringBuffer();

		String reportFile = "/report/GaugeChart1.jasper";
		try {
			JRBeanArrayDataSource dataSource = null;

			ChartData reportData = new DashboardBiz().getReportData(
					parameterName, startDate, endDate);

			// Set report type
			if (((Boolean) Constants.DASHBOARD_PARAMS_INVERSE
					.get(parameterName))) {
				// Inverse report
				reportFile = "/report/GaugeChart2.jasper";
			}

			ChartDataItem[] reportDataItems = reportData.getReportDataItems();

			dataSource = new JRBeanArrayDataSource(reportDataItems);

			JasperPrint jPrint = JasperFillManager.fillReport(request
					.getRealPath("/")
					+ reportFile, null, dataSource);

			List pages = jPrint.getPages();
			if (pages != null && pages.size() > 0) {
				JRHtmlExporter exporter = new JRHtmlExporter();
				request.getSession().setAttribute(
						ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE,
						jPrint);
				exporter.setParameter(JRExporterParameter.JASPER_PRINT, jPrint);
				exporter.setParameter(JRExporterParameter.OUTPUT_STRING_BUFFER,
						sb);
				exporter
						.setParameter(
								JRHtmlExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,
								Boolean.TRUE);
				exporter.setParameter(
						JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN,
						Boolean.FALSE);
				exporter.setParameter(JRExporterParameter.PAGE_INDEX, 0);
				exporter.setParameter(JRHtmlExporterParameter.HTML_HEADER, "");
				exporter.setParameter(
						JRHtmlExporterParameter.BETWEEN_PAGES_HTML, "");
				exporter.setParameter(JRHtmlExporterParameter.HTML_FOOTER, "");
				Map imagesMap = new HashMap(5);
				request.getSession().setAttribute("IMAGES_MAP", imagesMap);
				exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP,
						imagesMap);
				exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI,
						"image?image=");
				exporter.exportReport();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sb.toString();
	}
}
